#include "Epoll.h"
#include <unistd.h>
#include <iostream>
using namespace std;

Epoll::Epoll(int maxEvent): maxEvent_(maxEvent)
{
    epFd_ = epoll_create(1);
    if (epFd_ == -1) {
        perror("epoll_create");
        exit(1);
    }
    events = new epoll_event[maxEvent_];
}
vector<Channel*> Epoll::Wait(int timeout) {
    int n = epoll_wait(epFd_, events, maxEvent_, timeout);
    if (n == -1) {
        perror("epoll_wait");
        return {};
    }
    if (n == 0) {
        cout << "timeout" << endl;
        return {};
    }
    vector<Channel*> res;
    for (int i = 0; i < n; ++i) {
        Channel* ch = static_cast<Channel*>(events[i].data.ptr);
        ch->setRevents(events[i].events);
        res.push_back(ch);
    }
    return res;
}
void Epoll::updateChannel(Channel* ch) {
    epoll_event ev;
    ev.data.ptr = ch;
    ev.events = ch->getEvents();
    if (ch->inEpoll()) {
        epoll_ctl(epFd_, EPOLL_CTL_MOD, ch->getFd(), &ev);
    } else {
        epoll_ctl(epFd_, EPOLL_CTL_ADD, ch->getFd(), &ev);
        ch->setInEpoll();
    }
}
void Epoll::removeChannel(Channel* ch) {
    if (ch->inEpoll()) {
        epoll_ctl(epFd_, EPOLL_CTL_DEL, ch->getFd(), nullptr);
    }
}
Epoll::~Epoll()
{
    delete [] events;
    if (epFd_ == -1) return;
    close(epFd_);
}